# -*- coding: utf-8 -*-
"""
------------------------------------------------------------------------------
    File Name:  model_demo
    Author   :  wanwei1029
    Date     :  2018/12/20
    Desc     : model常用的方法有：
        1:add 用于添加层。
        2:compile
------------------------------------------------------------------------------
"""
from keras.layers import Dense
from keras.models import Sequential


def model_demo():
    model = Sequential()
    model.add(Dense(10, input_shape=(20, ), activation="softmax"))
    """
    compile编译模型，参数有：
    optimizer指定优化器，优化器都可带参数，目前有的优化器：SGD，RMSprop，Adagrad，Adadelta，Adam，Adamax，Nadam，TFOptimizer
        具体可见：keras.optimizers。两种使用方式 ：optimizer="adma"，optimizer=SGD().
    loss指定损失函数，常用的损失函数有：mean_squared_error或mse，mean_absolute_error或mae，mean_absolute_percentage_error或mape
        mean_squared_logarithmic_error或msle，squared_hinge，hinge，binary_crossentropy（亦称作对数损失，logloss）
        categorical_crossentropy：亦称作多类的对数损失，注意使用该目标函数时，需要将标签转化为形如(nb_samples, nb_classes)的二值序列
        sparse_categorical_crossentrop：如上，但接受稀疏标签。注意，使用该函数时仍然需要你的标签与输出值的维度相同，
        你可能需要在标签数据上增加一个维度：np.expand_dims(y,-1)
        kullback_leibler_divergence:从预测值概率分布Q到真值概率分布P的信息增益,用以度量两个分布的差异.
        cosine_proximity：即预测值与真实标签的余弦距离平均值的相反数
    metrics:评估标准，一般用metrics=["accuracy"]，即正确率来评估。
    """
    model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])
    """
    fit 训练模型，参数有：
    x: 输入数据，如果一个模型只有一个输入，则x是一个numpy array,如果模型有多个输入，则x是个list,list里元素都是numpy array.
    y: 标签数据，numpy array.
    batch_size: 整数，指定进行梯度下降时每个batch包含的样本数。训练时一个batch的样本会被计算一次梯度下降，使目标函数优化一步。
    epochs:迭代次数(训练轮数) 整数，训练终止时的epoch值，训练将在达到该epoch值时停止，当没有设置initial_epoch时，
            它就是训练的总轮数，否则训练的总轮数为epochs - inital_epoch
    verbose:日志显示，0为不在标准输出流输出日志信息，1为输出进度条记录，2为每个epoch输出一行记录
        注意，日志显示有四个参数：loss: 0.4218 - acc: 0.8873 - val_loss: 0.3896 - val_acc: 0.8984
        loss,acc 训练集上的损失率和准确率
        val_loss,val_acc 验证集上的损失率和准确率
    validation_split:0~1之间的浮点数，用来指定训练集的一定比例数据作为验证集。验证集将不参与训练，并在每个epoch结束后测试的模型的指标，
        如损失函数、精确度等。注意，validation_split的划分在shuffle之前，因此如果你的数据本身是有序的，
        需要先手工打乱再指定validation_split，否则可能会出现验证集样本不均匀。
        validation_data：形式为（x，y）的tuple，是指定的验证集。此参数将覆盖validation_spilt
    callbacks：list，其中的元素是keras.callbacks.Callback的对象。这个list中的回调函数将会在训练过程中的适当时机被调用，
        如定期保存模型参考回调函数
    fit返回一个history对象，可以保存下来用于分析调试(https://blog.csdn.net/xjcvip007/article/details/52801216)
    """
    model.fit()
    """
    evaluate指用测试集来评估模型，要注意区分训练集，验证集，测试集的区别，测试集和训练集是无交集的，验证集是从训练集中抽取的
    x:同fit
    y:同fit
    batch_size 默认32
    返回根据compile时指定的metrics来确定，如果是accuracy，则返回一个数组，第一个代表损失率，第二个是正确率。
    注意，此时返回的损失率和准确率是测试集上的，要和fit训练方法中的日志区分。
    """
    model.evaluate()
    x = [1, 1]
    """
    predict 用于网络训练好后进行的预测，输出每种结果的概率。
    predict_classes() 用于输出类别
    predict_proba() 用于输出概率 （没用过）
    """
    model.predict(x)


def demo():
    """
    """



if __name__ == '__main__':
    test_method = "demo"
    if test_method == "demo":
        demo()
